home *** CD-ROM | disk | FTP | other *** search
/ Aminet 43 / Aminet 43 (2001)(GTI - Schatztruhe)[!][Jun 2001].iso / Aminet / comm / mail / YAM22src.lha / YAM_EA.c < prev    next >
C/C++ Source or Header  |  2000-11-03  |  26KB  |  605 lines

  1. /***************************************************************************
  2.  
  3.  YAM - Yet Another Mailer
  4.  Copyright (C) 2000  Marcel Beck <mbeck@yam.ch>
  5.  
  6.  This program is free software; you can redistribute it and/or modify
  7.  it under the terms of the GNU General Public License as published by
  8.  the Free Software Foundation; either version 2 of the License, or
  9.  (at your option) any later version.
  10.  
  11.  This program is distributed in the hope that it will be useful,
  12.  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  GNU General Public License for more details.
  15.  
  16.  You should have received a copy of the GNU General Public License
  17.  along with this program; if not, write to the Free Software
  18.  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  
  20.  YAM Official Support Site :  http://www.yam.ch
  21.  YAM OpenSource project    :  http://sourceforge.net/projects/yamos/
  22.  
  23. ***************************************************************************/
  24.  
  25. #include "YAM.h"
  26.  
  27. /***************************************************************************
  28.  Module: Address book entry
  29. ***************************************************************************/
  30.  
  31. /*** Init & Open ***/
  32. /// EA_Init
  33. //  Creates and opens an address book entry window
  34. int EA_Init(int type, struct MUIS_Listtree_TreeNode *tn)
  35. {
  36.    struct EA_ClassData *ea;
  37.    int winnum;
  38.    char *title = "";
  39.    if ((winnum = EA_Open(type)) < 0) return -1;
  40.    ea = G->EA[winnum];
  41.    ea->EditNode   = tn;
  42.    switch (type)
  43.    {
  44.       case AET_USER:  title = tn ? GetStr(MSG_EA_EditUser) : GetStr(MSG_AB_AddUser); break;
  45.       case AET_LIST:  title = tn ? GetStr(MSG_EA_EditList) : GetStr(MSG_AB_AddList); break;
  46.       case AET_GROUP: title = tn ? GetStr(MSG_EA_EditGroup): GetStr(MSG_AB_AddGroup);
  47.    }
  48.    set(ea->GUI.WI, MUIA_Window_Title, title);
  49.    if (!SafeOpenWindow(ea->GUI.WI)) { DisposeModulePush(&G->EA[winnum]); return -1; }
  50.    set(ea->GUI.WI, MUIA_Window_ActiveObject, ea->GUI.ST_ALIAS);
  51.    return winnum;
  52. }       
  53. ///
  54. /// EA_Setup
  55. //  Setup GUI fields with data from adress book entry
  56. void EA_Setup(int winnum, struct ABEntry *ab)
  57. {
  58.    struct EA_GUIData *gui = &(G->EA[winnum]->GUI);
  59.    char *ptr;
  60.  
  61.    switch (ab->Type)
  62.    {
  63.       case AET_USER:   setstring(gui->ST_ALIAS, ab->Alias);
  64.                        setstring(gui->ST_REALNAME, ab->RealName);
  65.                        setstring(gui->ST_ADDRESS, ab->Address);
  66.                        setstring(gui->ST_PHONE, ab->Phone);
  67.                        setstring(gui->ST_STREET, ab->Street);
  68.                        setstring(gui->ST_CITY, ab->City);
  69.                        setstring(gui->ST_COUNTRY, ab->Country);
  70.                        setstring(gui->ST_PGPKEY, ab->PGPId);
  71.                        setstring(gui->ST_HOMEPAGE, ab->Homepage);
  72.                        setstring(gui->ST_COMMENT, ab->Comment);
  73.                        setstring(gui->ST_BIRTHDAY, AB_ExpandBD(ab->BirthDay));
  74.                        EA_SetPhoto(winnum, ab->Photo);
  75.                        break;
  76.       case AET_LIST:   setstring(gui->ST_ALIAS, ab->Alias);
  77.                        setstring(gui->ST_REALNAME, ab->RealName);
  78.                        setstring(gui->ST_ADDRESS, ab->Address);
  79.                        setstring(gui->ST_COMMENT, ab->Comment);
  80.                        DoMethod(gui->LV_MEMBER, MUIM_List_Clear);
  81.                        for (ptr = ab->Members; *ptr; ptr++)
  82.                        {
  83.                           char *nptr = strchr(ptr, '\n');
  84.                           if (nptr) *nptr = 0; else break;
  85.                           DoMethod(gui->LV_MEMBER, MUIM_List_InsertSingle, ptr, MUIV_List_Insert_Bottom);
  86.                           *nptr = '\n';
  87.                           ptr = nptr;
  88.                        }
  89.                        break;
  90.       case AET_GROUP:  setstring(gui->ST_ALIAS, ab->Alias);
  91.                        setstring(gui->ST_COMMENT, ab->Comment);
  92.                        break;
  93.    }
  94. }
  95. ///
  96.  
  97. /*** Private functions (member list) ***/
  98. /// EA_AddSingleMember
  99. //  Adds a single entry to the member list by Drag&Drop
  100. void EA_AddSingleMember(Object *obj, struct MUIS_Listtree_TreeNode *tn)
  101. {
  102.    struct ABEntry *ab;
  103.    int dropmark;
  104.    ab = tn->tn_User;
  105.    get(obj, MUIA_List_DropMark, &dropmark);
  106.    DoMethod(obj, MUIM_List_InsertSingle, ab->Alias ? ab->Alias : ab->RealName, dropmark);
  107. }
  108. ///
  109. /// EA_AddMembers (rec)
  110. //  Adds an entire group to the member list by Drag&Drop
  111. STACKEXT void EA_AddMembers(Object *obj, struct MUIS_Listtree_TreeNode *list)
  112. {
  113.    struct MUIS_Listtree_TreeNode *tn;
  114.    int i;
  115.    
  116.    for (i=0; ; i++)
  117.       if (tn = (struct MUIS_Listtree_TreeNode *)DoMethod(G->AB->GUI.LV_ADRESSES, MUIM_Listtree_GetEntry, list, i, MUIV_Lt_GetEntry_Flags_SameLevel))
  118.          if (tn->tn_Flags & TNF_LIST) EA_AddMembers(obj, tn);
  119.          else EA_AddSingleMember(obj, tn);
  120.       else break;
  121. }
  122. ///
  123. /// EA_GetEntry
  124. //  Fills string gadget with data from selected list entry
  125. SAVEDS ASM void EA_GetEntry(REG(a1) int *arg)
  126. {
  127.    int winnum = *arg;
  128.    char *entry = NULL;
  129.    DoMethod(G->EA[winnum]->GUI.LV_MEMBER, MUIM_List_GetEntry, MUIV_List_GetEntry_Active, &entry);
  130.    if (entry) nnset(G->EA[winnum]->GUI.ST_MEMBER, MUIA_String_Contents, entry);
  131. }
  132. MakeHook(EA_GetEntryHook, EA_GetEntry);
  133. ///
  134. /// EA_PutEntry
  135. //  Updates selected list entry
  136. SAVEDS ASM void EA_PutEntry(REG(a1) int *arg)
  137. {
  138.    struct EA_GUIData *gui = &(G->EA[*arg]->GUI);
  139.    extern struct Hook EA_AddHook;
  140.    char *buf;
  141.    int active;
  142.    
  143.    get(gui->LV_MEMBER, MUIA_List_Active, &active);
  144.    if (active == MUIV_List_Active_Off) DoMethod(G->App, MUIM_CallHook, &EA_AddHook, *arg);
  145.    else
  146.    {
  147.       get(gui->ST_MEMBER, MUIA_String_Contents, &buf);
  148.       DoMethod(gui->LV_MEMBER, MUIM_List_InsertSingle, buf, active);
  149.       DoMethod(gui->LV_MEMBER, MUIM_List_Remove, active+1);
  150.    }
  151. }
  152. MakeHook(EA_PutEntryHook, EA_PutEntry);
  153. ///
  154. /// EA_InsertBelowActive
  155. //  Inserts an entry into the address book tree
  156. void EA_InsertBelowActive(struct ABEntry *addr, int flags)
  157. {
  158.    APTR lt = G->AB->GUI.LV_ADRESSES;
  159.    struct TreeNode *node, *list, *res;
  160.    get(lt, MUIA_Listtree_Active, &node);
  161.    if (node == MUIV_Lt_Active_Off)
  162.    {
  163.       res = (struct TreeNode *)DoMethod(lt, MUIM_Listtree_Insert, addr->Alias, addr, MUIV_Lt_Insert_ListNode_Root, MUIV_Lt_Insert_PrevNode_Sorted, flags);
  164.    }
  165.    else
  166.    {
  167.       list = (struct TreeNode *)DoMethod(lt, MUIM_Listtree_GetEntry, MUIV_Lt_GetEntry_ListNode_Active, MUIV_Lt_GetEntry_Position_Parent, 0);
  168.       res = (struct TreeNode *)DoMethod(lt, MUIM_Listtree_Insert, addr->Alias, addr, list, node, flags);
  169.    }
  170. /*
  171.    
  172.    ULONG pred = DoMethod(lt, MUIM_Listtree_GetEntry, MUIV_Lt_GetEntry_ListNode_Active, MUIV_Lt_GetEntry_Position_Active, 0);
  173. */
  174.    if (res) set(lt, MUIA_Listtree_Active, res);
  175. }
  176. ///
  177. /// EA_FixAlias
  178. //  Avoids ambiguos aliases
  179. void EA_FixAlias(struct ABEntry *ab, BOOL excludemyself)
  180. {
  181.    char alias[SIZE_NAME];
  182.    int c = 1, l, hits = 0;
  183.    struct MUIS_Listtree_TreeNode *tn;
  184.    strcpy(alias, ab->Alias);
  185.    while (AB_SearchEntry(MUIV_Lt_GetEntry_ListNode_Root, alias, ASM_ALIAS|ASM_USER|ASM_LIST|ASM_GROUP, &hits, &tn))
  186.    {
  187.       if (tn->tn_User == ab && excludemyself && hits == 1) break;
  188.       if ((l = strlen(ab->Alias)) > SIZE_NAME-2) l = SIZE_NAME-2;
  189.       sprintf(&alias[l], "%ld", ++c); hits = 0;
  190.    }
  191.    strcpy(ab->Alias, alias);
  192. }
  193. ///
  194. /// EA_SetDefaultAlias
  195. //  Creates an alias from the real name if user left it empty
  196. void EA_SetDefaultAlias(struct ABEntry *ab)
  197. {
  198.    char *p = ab->Alias, *ln;
  199.  
  200.    clear(p, SIZE_NAME);
  201.    if (*ab->RealName)
  202.    {
  203.       if (ln = strrchr(ab->RealName, ' '))
  204.       {
  205.          if (isAlNum(ab->RealName[0])) { *p++ = ab->RealName[0]; *p++ = '_'; }
  206.          ln++;
  207.       }
  208.       else ln = ab->RealName;
  209.       for (; strlen(ab->Alias)<SIZE_NAME-2 && *ln; ln++) if (isAlNum(*ln)) *p++ = *ln;
  210.    }
  211.    else for (ln = ab->Address; strlen(ab->Alias)<SIZE_NAME-2 && *ln && *ln != '@'; ln++) if (isAlNum(*ln)) *p++ = *ln;
  212. }
  213. ///
  214.  
  215. /*** Buttons ***/
  216. /// EA_Okay
  217. //  Saves changes to the edited entry in the address book
  218. SAVEDS ASM void EA_Okay(REG(a1) int *arg)
  219. {
  220.    static struct ABEntry newaddr;
  221.    struct ABEntry *addr;
  222.    char *members, *str;
  223.    int i, winnum = *arg;
  224.    long bdate = 0;
  225.    struct EA_GUIData *gui = &(G->EA[winnum]->GUI);
  226.    BOOL old = G->EA[winnum]->EditNode != NULL;
  227.  
  228.    clear(&newaddr, sizeof(struct ABEntry));
  229.    if (G->EA[winnum]->Type)
  230.    {
  231.       get(gui->ST_ALIAS, MUIA_String_Contents, &str);
  232.       if (!*str) { ER_NewError(GetStr(MSG_ER_ErrorNoAlias), NULL, NULL); return; }
  233.    }
  234.    else
  235.    {
  236.       get(gui->ST_ADDRESS, MUIA_String_Contents, &str);
  237.       if (!*str) { ER_NewError(GetStr(MSG_ER_ErrorNoAddress), NULL, NULL); return; }
  238.       get(gui->ST_BIRTHDAY, MUIA_String_Contents, &str);
  239.       if (*str) if (!(bdate = AB_CompressBD(str))) { ER_NewError(GetStr(MSG_ER_ErrorDOBformat), NULL, NULL); return; }
  240.    }
  241.    set(gui->WI, MUIA_Window_Open, FALSE);
  242.    G->AB->Modified = TRUE;
  243.    if (old) addr = G->EA[winnum]->EditNode->tn_User; else addr = &newaddr;
  244.    GetMUIString(addr->Alias, gui->ST_ALIAS);
  245.    GetMUIString(addr->Comment, gui->ST_COMMENT);
  246.    switch (addr->Type = G->EA[winnum]->Type)
  247.    {
  248.       case AET_USER:  GetMUIString(addr->RealName, gui->ST_REALNAME);
  249.                       GetMUIString(addr->Address, gui->ST_ADDRESS);
  250.                       GetMUIString(addr->Phone, gui->ST_PHONE);
  251.                       GetMUIString(addr->Street, gui->ST_STREET);
  252.                       GetMUIString(addr->City, gui->ST_CITY);
  253.                       GetMUIString(addr->Country, gui->ST_COUNTRY);
  254.                       GetMUIString(addr->PGPId, gui->ST_PGPKEY);
  255.                       GetMUIString(addr->Homepage, gui->ST_HOMEPAGE);
  256.                       strcpy(addr->Photo, G->EA[winnum]->PhotoName);
  257.                       addr->BirthDay = bdate;
  258.                       if (!*addr->Alias) EA_SetDefaultAlias(addr);
  259.                       EA_FixAlias(addr, old);
  260.                       if (!old) EA_InsertBelowActive(addr, 0);
  261.                       break;
  262.       case AET_LIST:  GetMUIString(addr->RealName, gui->ST_REALNAME);
  263.                       GetMUIString(addr->Address, gui->ST_ADDRESS);
  264.                       members = AllocStrBuf(SIZE_DEFAULT);
  265.                       for (i = 0; ; i++)
  266.                       {
  267.                          char *p;
  268.                          DoMethod(gui->LV_MEMBER, MUIM_List_GetEntry, i, &p);
  269.                          if (!p) break;
  270.                          members = StrBufCat(members, p);
  271.                          members = StrBufCat(members, "\n");
  272.                       }
  273.                       if (old) addr->Members = realloc(addr->Members, strlen(members)+1);
  274.                       else     addr->Members = malloc(strlen(members)+1);
  275.                       strcpy(addr->Members, members);
  276.                       EA_FixAlias(addr, old);
  277.                       if (!old)
  278.                       {
  279.                          EA_InsertBelowActive(addr, 0);
  280.                          free(addr->Members);
  281.                       }
  282.                       FreeStrBuf(members);
  283.                       break;
  284.       case AET_GROUP: EA_FixAlias(addr, old);
  285.                       if (!old) EA_InsertBelowActive(addr, TNF_LIST);
  286.    }
  287.    if (old) DoMethod(G->AB->GUI.LV_ADRESSES, MUIM_List_Redraw, MUIV_List_Redraw_All);
  288.    else AppendLogVerbose(71, GetStr(MSG_LOG_NewAddress), addr->Alias, "", "", "");
  289.    DisposeModulePush(&G->EA[winnum]);
  290. }
  291. MakeHook(EA_OkayHook, EA_Okay);
  292. ///
  293. /// EA_AddFunc
  294. //  Adds a new entry to the member list
  295. SAVEDS ASM void EA_AddFunc(REG(a1) int *arg)
  296. {
  297.    struct EA_GUIData *gui = &(G->EA[*arg]->GUI);
  298.    char *buf;
  299.    
  300.    get(gui->ST_MEMBER, MUIA_String_Contents, &buf);
  301.    if (*buf) 
  302.    {
  303.       DoMethod(gui->LV_MEMBER, MUIM_List_InsertSingle, buf, MUIV_List_Insert_Bottom);
  304.       nnset(gui->LV_MEMBER, MUIA_List_Active, MUIV_List_Active_Off);
  305.       setstring(gui->ST_MEMBER, "");
  306.    }
  307.    set(gui->WI, MUIA_Window_ActiveObject, gui->ST_MEMBER);
  308. }
  309. MakeHook(EA_AddHook, EA_AddFunc);
  310. ///
  311. /// EA_SetPhoto
  312. //  Updates the portrait image
  313. void EA_SetPhoto(int winnum, char *fname)
  314. {
  315.    struct EA_GUIData *gui = &(G->EA[winnum]->GUI);
  316.  
  317.    if (fname) strcpy(G->EA[winnum]->PhotoName, fname);
  318.    fname = G->EA[winnum]->PhotoName;
  319.    if (*fname) if (DoMethod(gui->GR_PHOTO, MUIM_Group_InitChange))
  320.    {
  321.       DoMethod(gui->GR_PHOTO, OM_REMMEMBER, gui->BC_PHOTO);
  322.       MUI_DisposeObject(gui->BC_PHOTO);
  323.       gui->BC_PHOTO = MakePicture(fname);
  324.       DoMethod(gui->GR_PHOTO, OM_ADDMEMBER, gui->BC_PHOTO);
  325.       DoMethod(gui->GR_PHOTO, MUIM_Group_ExitChange);
  326.    }
  327. }
  328. ///
  329. /// EA_SelectPhotoFunc
  330. //  Lets user select an image file to be used as portrait
  331. SAVEDS ASM void EA_SelectPhotoFunc(REG(a1) int *arg)
  332. {
  333.    int winnum = *arg;
  334.  
  335.    if (ReqFile(ASL_PHOTO,G->EA[winnum]->GUI.WI, GetStr(MSG_EA_SelectPhoto), 0, C->GalleryDir, ""))
  336.    {
  337.       strmfp(G->EA[winnum]->PhotoName, G->ASLReq[ASL_PHOTO]->fr_Drawer, G->ASLReq[ASL_PHOTO]->fr_File);
  338.       EA_SetPhoto(winnum, NULL);
  339.    }
  340. }
  341. MakeHook(EA_SelectPhotoHook, EA_SelectPhotoFunc);
  342. ///
  343. /// EA_DownloadPhotoFunc
  344. //  Downloads a portrait from the YAM user gallery
  345. SAVEDS ASM void EA_DownloadPhotoFunc(REG(a1) int *arg)
  346. {
  347.    int winnum = *arg, c;
  348.    struct EA_GUIData *gui = &(G->EA[winnum]->GUI);
  349.    char *p, dbfile[SIZE_PATHFILE], *name, *addr, *homepage, newname[SIZE_DEFAULT], dbentry[5][SIZE_DEFAULT];
  350.    BOOL success = FALSE;
  351.    FILE *db;
  352.  
  353.    get(gui->ST_REALNAME, MUIA_String_Contents, &name);
  354.    get(gui->ST_ADDRESS, MUIA_String_Contents, &addr);
  355.    get(gui->ST_HOMEPAGE, MUIA_String_Contents, &homepage);
  356.    if (*addr || *name)
  357.    {
  358.       strcpy(dbfile, name);
  359.       if (p = strrchr(dbfile, ' ')) { *p = 0; sprintf(newname, "%s, %s", p+1, dbfile); }
  360.       else strcpy(newname, name);
  361.       strmfp(dbfile, C->TempDir, "gallery.db");
  362.       if (TR_OpenTCPIP())
  363.       {
  364.          Busy(GetStr(MSG_BusyDownloadingPic), name, 0, 0);
  365.          if (!(db = fopen(dbfile, "r")))
  366.             if (TR_DownloadURL(C->SupportSite, "gallery", "database", dbfile))
  367.                db = fopen(dbfile, "r");
  368.          if (db)
  369.          {
  370.             for (c = 0; GetLine(db, dbentry[c], SIZE_DEFAULT); c++) if (c == 4)
  371.             {
  372.                c = -1;
  373.                if (!stricmp(dbentry[0], name) || !stricmp(dbentry[0], newname) || !stricmp(dbentry[1], addr))
  374.                {
  375.                   if (!*name) setstring(gui->ST_REALNAME, dbentry[0]);
  376.                   if (!*addr) setstring(gui->ST_ADDRESS, dbentry[1]);
  377.                   if (!*homepage) setstring(gui->ST_HOMEPAGE, dbentry[3]);
  378.                   CreateDirectory(C->GalleryDir);
  379.                   strmfp(dbfile, C->GalleryDir, FilePart(dbentry[2]));
  380.                   if (TR_DownloadURL(C->SupportSite, "gallery", dbentry[2], dbfile)) EA_SetPhoto(winnum, dbfile);
  381.                   success = TRUE; break;
  382.                }
  383.             }
  384.             fclose(db);
  385.             if (!success) ER_NewError(GetStr(MSG_ER_NotInGallery), NULL, NULL);
  386.          }
  387.          BusyEnd;
  388.          TR_CloseTCPIP();
  389.       }
  390.       else ER_NewError(GetStr(MSG_ER_NoTCP), NULL, NULL);
  391.    }
  392. }
  393. MakeHook(EA_DownloadPhotoHook, EA_DownloadPhotoFunc);
  394. ///
  395. /// EA_HomepageFunc
  396. //  Launches a browser to view the homepage of the person
  397. SAVEDS ASM void EA_HomepageFunc(REG(a1) int *arg)
  398. {
  399.    char *url;
  400.    get(G->EA[*arg]->GUI.ST_HOMEPAGE, MUIA_String_Contents, &url);
  401.    if (*url) GotoURL(url);
  402. }
  403. MakeHook(EA_HomepageHook, EA_HomepageFunc);
  404. ///
  405. /// EA_Open
  406. //  Assigns a number for a new window
  407. int EA_Open(int type)
  408. {
  409.    int winnum;
  410.    for (winnum = 0; winnum < 4; winnum++) if (!G->EA[winnum]) break;
  411.    if (winnum == 4) return -1;
  412.    if (!(G->EA[winnum] = EA_New(winnum, type))) return -1;
  413.    return winnum;
  414. }
  415. ///
  416. /// EA_CloseFunc
  417. //  Closes address book entry window
  418. SAVEDS ASM void EA_CloseFunc(REG(a1) int *arg)
  419. {
  420.    int winnum = *arg;
  421.    DisposeModulePush(&G->EA[winnum]);
  422. }
  423. MakeHook(EA_CloseHook, EA_CloseFunc);
  424. ///
  425.  
  426. /*** GUI ***/
  427. /// EA_New
  428. //  Creates address book entry window
  429. struct EA_ClassData *EA_New(int winnum, int type)
  430. {
  431.    struct EA_ClassData *data;
  432.  
  433.    if (data = calloc(1,sizeof(struct EA_ClassData)))
  434.    {
  435.       APTR group = NULL, bt_homepage, bt_sort;
  436.       data->Type = type;
  437.       switch (type)
  438.       {
  439.          case AET_USER: group = HGroup,
  440.                MUIA_Group_SameWidth, TRUE,
  441.                Child, VGroup,
  442.                   Child, ColGroup(2), GroupFrameT(GetStr(MSG_EA_ElectronicMail)),
  443.                      Child, Label2(GetStr(MSG_EA_Alias)),
  444.                      Child, data->GUI.ST_ALIAS = MakeString(SIZE_NAME,GetStr(MSG_EA_Alias)),
  445.                      Child, Label2(GetStr(MSG_EA_RealName)),
  446.                      Child, data->GUI.ST_REALNAME = MakeString(SIZE_REALNAME,GetStr(MSG_EA_RealName)),
  447.                      Child, Label2(GetStr(MSG_EA_EmailAddress)),
  448.                      Child, data->GUI.ST_ADDRESS  = MakeString(SIZE_ADDRESS,GetStr(MSG_EA_EmailAddress)),
  449.                      Child, Label2(GetStr(MSG_EA_PGPId)),
  450.                      Child, MakePGPKeyList(&(data->GUI.ST_PGPKEY), FALSE, GetStr(MSG_EA_PGPId)),
  451.                      Child, Label2(GetStr(MSG_EA_Homepage)),
  452.                      Child, HGroup,
  453.                         MUIA_Group_HorizSpacing, 1,
  454.                         Child, data->GUI.ST_HOMEPAGE = MakeString(SIZE_URL,GetStr(MSG_EA_Homepage)),
  455.                         Child, bt_homepage = PopButton(MUII_TapeRecord),
  456.                      End,
  457.                   End,
  458.                   Child, ColGroup(2), GroupFrameT(GetStr(MSG_EA_SnailMail)),
  459.                      Child, Label2(GetStr(MSG_EA_Street)),
  460.                      Child, data->GUI.ST_STREET = MakeString(SIZE_DEFAULT,GetStr(MSG_EA_Street)),
  461.                      Child, Label2(GetStr(MSG_EA_City)),
  462.                      Child, data->GUI.ST_CITY = MakeString(SIZE_DEFAULT,GetStr(MSG_EA_City)),
  463.                      Child, Label2(GetStr(MSG_EA_Country)),
  464.                      Child, data->GUI.ST_COUNTRY = MakeString(SIZE_DEFAULT,GetStr(MSG_EA_Country)),
  465.                      Child, Label2(GetStr(MSG_EA_Phone)),
  466.                      Child, data->GUI.ST_PHONE = MakeString(SIZE_DEFAULT,GetStr(MSG_EA_Phone)),
  467.                   End,
  468.                End,
  469.                Child, VGroup,
  470.                   Child, ColGroup(2), GroupFrameT(GetStr(MSG_EA_Miscellaneous)),
  471.                      Child, Label2(GetStr(MSG_EA_Description)),
  472.                      Child, data->GUI.ST_COMMENT = MakeString(SIZE_DEFAULT,GetStr(MSG_EA_Description)),
  473.                      Child, Label2(GetStr(MSG_EA_DOB)),
  474.                      Child, data->GUI.ST_BIRTHDAY = MakeString(SIZE_SMALL,GetStr(MSG_EA_DOB)),
  475.                   End,
  476.                   Child, VGroupV, GroupFrameT(GetStr(MSG_EA_Portrait)),
  477.                      Child, ColGroup(2),
  478.                         Child, data->GUI.BT_SELECTPHOTO = MakeButton(GetStr(MSG_EA_SelectPhoto)),
  479.                         Child, data->GUI.BT_LOADPHOTO = MakeButton(GetStr(MSG_EA_LoadPhoto)),
  480.                      End,
  481.                      Child, HGroup,
  482.                         Child, HSpace(0),
  483.                         Child, data->GUI.GR_PHOTO = HGroup,
  484.                            Child, data->GUI.BC_PHOTO = RectangleObject, MUIA_FixWidth, 100, MUIA_FixHeight, 80, End,
  485.                            ImageButtonFrame,
  486.                         End,
  487.                         Child, HSpace(0),
  488.                      End,
  489.                      Child, VSpace(0),
  490.                   End,
  491.                End,
  492.             End; 
  493.             if (group) 
  494.             {
  495.                set(data->GUI.BT_LOADPHOTO, MUIA_Disabled, !*C->GalleryDir);
  496.                SetHelp(data->GUI.ST_REALNAME   ,MSG_HELP_EA_ST_REALNAME   );
  497.                SetHelp(data->GUI.ST_ADDRESS    ,MSG_HELP_EA_ST_ADDRESS    );
  498.                SetHelp(data->GUI.ST_PGPKEY     ,MSG_HELP_EA_ST_PGPKEY     );
  499.                SetHelp(data->GUI.ST_HOMEPAGE   ,MSG_HELP_EA_ST_HOMEPAGE   );
  500.                SetHelp(data->GUI.ST_STREET     ,MSG_HELP_EA_ST_STREET     );
  501.                SetHelp(data->GUI.ST_CITY       ,MSG_HELP_EA_ST_CITY       );
  502.                SetHelp(data->GUI.ST_COUNTRY    ,MSG_HELP_EA_ST_COUNTRY    );
  503.                SetHelp(data->GUI.ST_PHONE      ,MSG_HELP_EA_ST_PHONE      );
  504.                SetHelp(data->GUI.ST_BIRTHDAY   ,MSG_HELP_EA_ST_BIRTHDAY   );
  505.                SetHelp(data->GUI.BC_PHOTO      ,MSG_HELP_EA_BC_PHOTO      );
  506.                SetHelp(data->GUI.BT_SELECTPHOTO,MSG_HELP_EA_BT_SELECTPHOTO);
  507.                SetHelp(data->GUI.BT_LOADPHOTO  ,MSG_HELP_EA_BT_LOADPHOTO  );
  508.                DoMethod(data->GUI.BT_SELECTPHOTO, MUIM_Notify, MUIA_Pressed, FALSE, MUIV_Notify_Application, 3, MUIM_CallHook, &EA_SelectPhotoHook, winnum);
  509.                DoMethod(data->GUI.BT_LOADPHOTO,   MUIM_Notify, MUIA_Pressed, FALSE, MUIV_Notify_Application, 3, MUIM_CallHook, &EA_DownloadPhotoHook, winnum);
  510.                DoMethod(bt_homepage, MUIM_Notify, MUIA_Pressed, FALSE, MUIV_Notify_Application, 3, MUIM_CallHook, &EA_HomepageHook, winnum);
  511.             }
  512.             break;
  513.          case AET_GROUP: group = ColGroup(2), GroupFrame,
  514.                MUIA_Background, MUII_GroupBack,
  515.                Child, Label2(GetStr(MSG_EA_Alias)),
  516.                Child, data->GUI.ST_ALIAS = MakeString(SIZE_NAME,GetStr(MSG_EA_Alias)),
  517.                Child, Label2(GetStr(MSG_EA_Description)),
  518.                Child, data->GUI.ST_COMMENT = MakeString(SIZE_DEFAULT,GetStr(MSG_EA_Description)),
  519.             End; break;
  520.          case AET_LIST: group = HGroup,
  521.                MUIA_Group_SameWidth, TRUE,
  522.                Child, VGroup,
  523.                   Child, ColGroup(2), GroupFrameT(GetStr(MSG_EA_ElectronicMail)),
  524.                      MUIA_Background, MUII_GroupBack,
  525.                      Child, Label2(GetStr(MSG_EA_Alias)),
  526.                      Child, data->GUI.ST_ALIAS = MakeString(SIZE_NAME,GetStr(MSG_EA_Alias)),
  527.                      Child, Label2(GetStr(MSG_EA_ReturnAddress)),
  528.                      Child, data->GUI.ST_ADDRESS = MakeString(SIZE_ADDRESS,GetStr(MSG_EA_ReturnAddress)),
  529.                      Child, Label2(GetStr(MSG_EA_MLName)),
  530.                      Child, data->GUI.ST_REALNAME = MakeString(SIZE_REALNAME,GetStr(MSG_EA_MLName)),
  531.                      Child, Label2(GetStr(MSG_EA_Description)),
  532.                      Child, data->GUI.ST_COMMENT = MakeString(SIZE_DEFAULT,GetStr(MSG_EA_Description)),
  533.                   End,
  534.                   Child, VSpace(0),
  535.                End,
  536.                Child, VGroup, GroupFrameT(GetStr(MSG_EA_Members)),
  537.                   Child, ListviewObject,
  538.                      MUIA_CycleChain, 1,
  539.                      MUIA_Listview_DragType, 1,
  540.                      MUIA_Listview_List, data->GUI.LV_MEMBER = NewObject(CL_DDList->mcc_Class,NULL,
  541.                         InputListFrame,
  542.                         MUIA_List_DragSortable ,TRUE,
  543.                         MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
  544.                         MUIA_List_DestructHook ,MUIV_List_DestructHook_String,
  545.                      End,
  546.                   End,
  547.                   Child, data->GUI.ST_MEMBER = MakeString(SIZE_ADDRESS,""),
  548.                   Child, ColGroup(3), GroupSpacing(0),
  549.                      Child, data->GUI.BT_ADD = MakeButton(GetStr(MSG_Add)),
  550.                      Child, data->GUI.BT_DEL = MakeButton(GetStr(MSG_Del)),
  551.                      Child, bt_sort          = MakeButton(GetStr(MSG_EA_Sort)),
  552.                   End,
  553.                End,
  554.             End; 
  555.             if (group)
  556.             {
  557.                SetHelp(data->GUI.ST_ALIAS   ,MSG_HELP_EA_ST_ALIAS      );
  558.                SetHelp(data->GUI.ST_COMMENT ,MSG_HELP_EA_ST_DESCRIPTION);
  559.                SetHelp(data->GUI.ST_REALNAME,MSG_HELP_EA_ST_REALNAME_L );
  560.                SetHelp(data->GUI.ST_ADDRESS ,MSG_HELP_EA_ST_ADDRESS_L  );
  561.                SetHelp(data->GUI.LV_MEMBER  ,MSG_HELP_EA_LV_MEMBERS    );
  562.                SetHelp(data->GUI.ST_MEMBER  ,MSG_HELP_EA_ST_MEMBER     );
  563.                SetHelp(data->GUI.BT_ADD     ,MSG_HELP_EA_BT_ADD        );
  564.                SetHelp(data->GUI.BT_DEL     ,MSG_HELP_EA_BT_DEL        );
  565.                SetHelp(bt_sort              ,MSG_HELP_EA_BT_SORT       );
  566.                DoMethod(data->GUI.BT_ADD   ,MUIM_Notify,MUIA_Pressed            ,FALSE         ,MUIV_Notify_Application,3,MUIM_CallHook   ,&EA_AddHook,winnum);
  567.                DoMethod(data->GUI.BT_DEL   ,MUIM_Notify,MUIA_Pressed            ,FALSE         ,data->GUI.LV_MEMBER,2,MUIM_List_Remove,MUIV_List_Remove_Active);
  568.                DoMethod(bt_sort            ,MUIM_Notify,MUIA_Pressed            ,FALSE         ,data->GUI.LV_MEMBER,1,MUIM_List_Sort);
  569.                DoMethod(data->GUI.ST_MEMBER,MUIM_Notify,MUIA_String_Acknowledge ,MUIV_EveryTime,MUIV_Notify_Application,3,MUIM_CallHook   ,&EA_PutEntryHook,winnum);
  570.                DoMethod(data->GUI.LV_MEMBER,MUIM_Notify,MUIA_List_Active        ,MUIV_EveryTime,MUIV_Notify_Application,3,MUIM_CallHook   ,&EA_GetEntryHook,winnum);
  571.             }
  572.             break;
  573.       }
  574.       data->GUI.WI = WindowObject,
  575.          MUIA_Window_Title, "",
  576.          MUIA_HelpNode, "EA_W",
  577.          MUIA_Window_ID, MAKE_ID('E','D','A','D'),
  578.          WindowContents, VGroup,
  579.             Child, group,
  580.             Child, ColGroup(3),
  581.                Child, data->GUI.BT_OKAY   = MakeButton(GetStr(MSG_Okay)),
  582.                Child, HSpace(0),
  583.                Child, data->GUI.BT_CANCEL = MakeButton(GetStr(MSG_Cancel)),
  584.             End,
  585.          End,
  586.       End;
  587.      if (data->GUI.WI)
  588.      {
  589.          DoMethod(G->App, OM_ADDMEMBER, data->GUI.WI);
  590.          SetHelp(data->GUI.ST_ALIAS   ,MSG_HELP_EA_ST_ALIAS      );
  591.          SetHelp(data->GUI.ST_COMMENT ,MSG_HELP_EA_ST_DESCRIPTION);
  592.          SetHelp(data->GUI.BT_OKAY    ,MSG_HELP_EA_BT_OKAY       );
  593.          SetHelp(data->GUI.BT_CANCEL  ,MSG_HELP_EA_BT_CANCEL     );
  594.          set(data->GUI.ST_BIRTHDAY, MUIA_String_Accept, "0123456789-AaBbCcDdEeFfGgJjLlMmNnOoPpRrSsTtUuVvYy");
  595.          DoMethod(data->GUI.BT_CANCEL,MUIM_Notify,MUIA_Pressed            ,FALSE         ,MUIV_Notify_Application,3,MUIM_CallHook,&EA_CloseHook,winnum);
  596.          DoMethod(data->GUI.BT_OKAY  ,MUIM_Notify,MUIA_Pressed            ,FALSE         ,MUIV_Notify_Application,3,MUIM_CallHook,&EA_OkayHook,winnum);
  597.          DoMethod(data->GUI.WI       ,MUIM_Notify,MUIA_Window_CloseRequest,TRUE          ,MUIV_Notify_Application,3,MUIM_CallHook,&EA_CloseHook,winnum);
  598.          return data;
  599.       }
  600.       free(data);
  601.    }
  602.    return NULL;
  603. }
  604. ///
  605.